import {
  CallHandler,
  ExecutionContext,
  Injectable,
  Logger,
  NestInterceptor,
} from '@nestjs/common';
import { Observable, tap } from 'rxjs';
import { Request } from 'express';
import { v4 as uuid } from 'uuid';
/**
 * 日志拦截器
 */
@Injectable()
export class LogInterceptorInterceptor implements NestInterceptor {
  private readonly logger = new Logger();

  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    const request = context.switchToHttp().getRequest<Request>();
    let params = {};
    if (Object.keys(request.query).length > 0) {
      params = { ...params, ...request.query };
    }
    if (Object.keys(request.params).length > 0) {
      params = { ...params, ...request.params };
    }
    if (Object.keys(request.body).length > 0) {
      params = { ...params, ...request.body };
    }

    const { method, path } = request;
    const startTime = Date.now();
    const className = context.getClass().name;
    const traceId = uuid();
    request['traceId'] = traceId;
    return next.handle().pipe(
      tap((data) => {
        const diff = `+${Date.now() - startTime}ms`;
        let responseData = data ? data : '';
        typeof responseData === 'object' &&
          (responseData = JSON.stringify(responseData));
        this.logger.log(
          `${traceId} ${className} ${method} ${path} request: ${JSON.stringify(params)} response: ${JSON.stringify(responseData)} ${diff}`,
        );
      }),
    );
  }
}
